/**
 * @link https://leetcode.cn/problems/minimum-size-subarray-sum/?envType=study-plan-v2&envId=top-interview-150
 */
function minSubArrayLen(target: number, nums: number[]): number {
  for (let m = 0; m < nums.length; m++) {
    if (nums[m] >= target) {
      return 1;
    }
  }
  if (nums.length === 1) {
    return 0;
  }
  let i = 0;
  let j = 1;
  let ans = Infinity;
  let curVal = nums[0] + nums[1];

  while (j < nums.length) {
    console.log(curVal, i, j);

    if (curVal > target) {
      ans = Math.min(ans, j - i + 1);
      curVal -= nums[i];
      i += 1;
    } else if (curVal === target) {
      ans = Math.min(ans, j - i + 1);
      curVal -= nums[i];
      i += 1;
      curVal += nums[j + 1];
      j += 1;
    } else {
      curVal += nums[j + 1];
      j += 1;
    }
  }
  console.log(ans);

  return ans !== Infinity ? ans : 0;
}

/**
 * @link https://leetcode.cn/problems/longest-substring-without-repeating-characters/?envType=study-plan-v2&envId=top-interview-150
 */
function lengthOfLongestSubstring(s: string): number {
  if (s === "") return 0;
  let i = 0;
  let j = 1;
  let cur = s[0];
  let ans = 1;
  while (j < s.length) {
    if (cur.includes(s[j])) {
      cur = cur.substring(cur.indexOf(s[j]) + 1, cur.length);
      i += 1;
      cur += s[j];
      j += 1;
    } else {
      cur += s[j];
      ans = Math.max(ans, cur.length);
      j += 1;
    }
    console.log(cur, ans);
  }
  return ans;
}

/**
 * @link https://leetcode.cn/problems/find-all-anagrams-in-a-string/solutions/1123971/zhao-dao-zi-fu-chuan-zhong-suo-you-zi-mu-xzin/
 */
function findAnagrams(s: string, p: string): number[] {
  let pLen = p.length;
  let sLen = s.length;

  if (sLen < pLen) return [];

  let ans = [];

  let differ = 0;

  let count = Array(26).fill(0);

  for (let i = 0; i < pLen; i++) {
    ++count[s[i].charCodeAt(0) - "a".charCodeAt(0)];
    --count[p[i].charCodeAt(0) - "a".charCodeAt(0)];
  }

  for (let i = 0; i < 26; i++) {
    if (count[i]) {
      ++differ;
    }
  }

  if (!differ) {
    ans.push(0);
  }

  for (let i = 0; i < sLen - pLen; i++) {
    if (count[s[i].charCodeAt(0) - "a".charCodeAt(0)] === 1) {
      --differ;
    } else if (count[s[i].charCodeAt(0) - "a".charCodeAt(0)] === 0) {
      ++differ;
    }
    --count[s[i].charCodeAt(0) - "a".charCodeAt(0)];

    if (count[s[i + pLen].charCodeAt(0) - "a".charCodeAt(0)] === -1) {
      --differ;
    } else if (count[s[i + pLen].charCodeAt(0) - "a".charCodeAt(0)] === 0) {
      ++differ;
    }
    ++count[s[i + pLen].charCodeAt(0) - "a".charCodeAt(0)];
    if (!differ) {
      ans.push(i + 1);
    }
  }
  console.log(ans);

  return ans;
}

/**
 * @link https://leetcode.cn/problems/substring-with-concatenation-of-all-words/?envType=study-plan-v2&envId=top-interview-150
 */
function findSubstring(s: string, words: string[]): number[] {
  let ans: number[] = [];

  let wordLen = words[0].length;
  let wordsLen = words.length;
  let strLen = s.length;

  for (let i = 0; i < wordLen; i++) {
    if (i + wordLen * wordsLen > strLen) {
      break;
    }

    let differ = new Map();

    for (let j = 0; j < wordsLen; j++) {
      const word = s.substring(i + j * wordLen, i + (j + 1) * wordLen);
      differ.set(word, (differ.get(word) || 0) + 1);
    }

    for (let word of words) {
      differ.set(word, (differ.get(word) || 0) - 1);
      if (differ.get(word) === 0) {
        differ.delete(word);
      }
    }

    for (
      let start = i;
      start < strLen - wordLen * wordsLen + 1;
      start += wordLen
    ) {
      if (start !== i) {
        let word = s.substring(
          start + (wordsLen - 1) * wordLen,
          start + wordsLen * wordLen
        );
        differ.set(word, (differ.get(word) || 0) + 1);

        if (differ.get(word) === 0) {
          differ.delete(word);
        }

        word = s.substring(start - wordLen, start);
        differ.set(word, (differ.get(word) || 0) - 1);
        if (differ.get(word) === 0) {
          differ.delete(word);
        }
      }

      console.log(differ);

      if (differ.size === 0) {
        ans.push(start);
      }
    }
  }

  console.log(ans);

  return ans;
}

/**
 * @link https://leetcode.cn/problems/minimum-window-substring/?envType=study-plan-v2&envId=top-interview-150
 */
function minWindow(s: string, t: string): string {
  let ans = "";

  let width = t.length;

  while (width <= s.length) {
    let differ = 0;
    let count = Array(26).fill(0);

    for (let i = 0; i < width; i++) {
      ++count[s[i].charCodeAt(0) - "a".charCodeAt(0)];
    }

    for (let i = 0; i < t.length; i++) {
      --count[s[i].charCodeAt(0) - "a".charCodeAt(0)];
    }

    console.log([...count]);

    for (let i = 0; i < 26; i++) {
      if (t.includes(i + "a") && count[i] !== 0) {
        ++differ;
      }
    }

    console.log(differ);

    if (differ === 0) {
      return s.substring(0, width);
    }

    for (let i = 0; i < s.length - width; i++) {
      if (
        t.includes(s[i]) &&
        count[s[i].charCodeAt(0) - "a".charCodeAt(0)] === 1
      ) {
        --differ;
      } else if (
        t.includes(s[i]) &&
        count[s[i].charCodeAt(0) - "a".charCodeAt(0)] === 0
      ) {
        ++differ;
      }
      --count[s[i].charCodeAt(0) - "a".charCodeAt(0)];

      if (
        t.includes(s[i + width]) &&
        count[s[i + width].charCodeAt(0) - "a".charCodeAt(0)] === -1
      ) {
        --differ;
      } else if (
        t.includes(s[i + width]) &&
        count[s[i + width].charCodeAt(0) - "a".charCodeAt(0)] === 0
      ) {
        ++differ;
      }
      ++count[s[i + width].charCodeAt(0) - "a".charCodeAt(0)];
    }

    width++;
    console.log(count);
  }

  return ans;
}

export default {
  minSubArrayLen,
  lengthOfLongestSubstring,
  findSubstring,
  findAnagrams,
  minWindow,
};
